﻿using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using MVVM_CAD.Common;
using MVVM_CAD.Model;
using MVVM_CAD.Strategy;
using MVVM_CAD.ViewModel;
using Ninject;
using WPF_CAD.Test.Common;

namespace WPF_CAD.Test.ViewModel
{
    /// <summary>
    /// Summary description for MainWindowTestFixture
    /// </summary>
    [TestClass]
    public class MainWindowTestFixture
    {
        private IKernel _kernel;
        private MainViewModel _viewModel;

        [TestInitialize]
        public void SetUp()
        {
            //Arrange
            _kernel = new StandardKernel(new TestNinjectModule());
            var mock = new Mock<IStrategy>();
            _viewModel = new MainViewModel();
        }

        [TestCleanup]
        public void CleanUp()
        {
            _kernel.Dispose();
        }

        [TestMethod]
        public void CreateMainWindowViewModel()
        {
            //Act
            _viewModel = _kernel.Get<MainViewModel>();
            //Assert
            Assert.IsNotNull(_viewModel);
        }

        [TestMethod]
        public void CreateMainWindowViewModelWithStrategy()
        {
            //Act
            _viewModel = _kernel.Get<MainViewModel>();
            //Assert
            Assert.IsNotNull(_viewModel);
        }

        

        #region Storing Figures
        [TestMethod]
        public void StoreDrawedFigures()
        {
            //Arrange
            var lineStrategy = _kernel.Get<LineToolStrategy>();
            var canvas = new Canvas();
            var mockPoint = new Mock<IPoint>();

            //Act
            var figuresStored = _viewModel.DrawedFigures.Count;
            var figureDrawed = lineStrategy.PerformMouseLeftClicDownEvent(canvas, mockPoint.Object, null);
            _viewModel.DrawedFigures.Add(figureDrawed);

            //Assert
            Assert.IsTrue(figuresStored < _viewModel.DrawedFigures.Count);
            Assert.AreEqual(figuresStored + 1, _viewModel.DrawedFigures.Count);
        }

        [TestMethod]
        public void StoreFiguresNoStoreIncompleteFigures()
        {
            //Arrange
            var mockFigure = new Mock<IFigure>();
            mockFigure.Setup(f => f.DrawStatus).Returns(DrawStatus.Incompleted);
            //Act
            _viewModel.AddFigure(mockFigure.Object);
            //Assert
            mockFigure.Verify(f => f.DrawStatus);
            Assert.AreEqual(_viewModel.DrawedFigures.Count, 0);
        }

        [TestMethod]
        public void StoreFiguresStoreCompleteFigures()
        {
            //Arrange
            var mockFigure = new Mock<IFigure>();
            mockFigure.Setup(f => f.DrawStatus).Returns(DrawStatus.Completed);
            //Act
            _viewModel.AddFigure(mockFigure.Object);
            //Assert
            mockFigure.Verify(f => f.DrawStatus);
            Assert.AreEqual(_viewModel.DrawedFigures.Count, 1);
        }

        #endregion

        /*
         * MainWindowViewModel va a tener un objeto observable que es SelectedFigure.
         * Este SelectedFigure va a cambiar cada vez que se seleccione una figura con la 
         * herramienta de seleccion.
         */
        [TestMethod]
        public void SelectedObject()
        {
            //Arrange
            var strategy = _kernel.Get<SelectionToolStrategy>();
            var line = new Line();
            var canvas = new Canvas();
            line.PointsCollection.Add(new CustomPoint(70, 80));
            _viewModel.SelectedFigure = new Point();
            _viewModel.SelectedFigure.PointsCollection.Add(new CustomPoint(50, 50));
            _viewModel.DrawedFigures.Add(line);
            //Act
            _viewModel.AddFigure(strategy.PerformMouseLeftClicDownEvent(canvas, new CustomPoint(70, 80),
                                                                        _viewModel.DrawedFigures));
            //
            Assert.AreEqual(_viewModel.SelectedFigure, line);
        }

        [TestMethod]
        public void SelectedObjectFail()
        {
            //Arrange
            var strategy = _kernel.Get<SelectionToolStrategy>();
            var line = new Line();
            var canvas = new Canvas();
            line.PointsCollection.Add(new CustomPoint(70, 81));
            _viewModel.SelectedFigure = new Point();
            _viewModel.SelectedFigure.PointsCollection.Add(new CustomPoint(50, 50));
            var figure = _viewModel.SelectedFigure;
            _viewModel.DrawedFigures.Add(line);
            //Act
            _viewModel.AddFigure(strategy.PerformMouseLeftClicDownEvent(canvas, new CustomPoint(70, 80),
                                                                        _viewModel.DrawedFigures));
            //Assert
            Assert.AreNotEqual(_viewModel.SelectedFigure, line);
            Assert.AreEqual(_viewModel.SelectedFigure, figure);
        }

        [TestMethod]
        public void SelectPerformSelection()
        {
            //Arrange
            var strategy = _kernel.Get<SelectionToolStrategy>();
            var point = new Mock<IPoint>();
            var canvas = new Canvas();
            strategy.Figure.PointsCollection.Add(point.Object);
            strategy.Figure.DrawStatus = DrawStatus.Completed;
            //Act
            strategy.PerformMouseLeftClicDownEvent(canvas, point.Object, new List<IFigure>());

            point.Verify();
        }


        #region Manipulation of SelectedFigure

        [TestMethod]
        public void ChangeXCoordinateOfPoints()
        {
            //Arrange
            var xIncrement = 5.5;
            _viewModel.Canvas = new DrawingCanvas();
            _viewModel.SelectedFigure = new Line();
            _viewModel.SelectedFigure.PointsCollection.Add(new CustomPoint(0, 0));
            _viewModel.SelectedFigure.PointsCollection.Add(new CustomPoint(1, 1));
            _viewModel.SelectedFigure.PointsCollection.Add(new CustomPoint(5, 5));
            _viewModel.SelectedFigure.PointsCollection.Add(new CustomPoint(7, 7));
            //Act
            //_viewModel.IncrementXCoordinateOfPointsInFigure(xIncrement);
            //Assert
            Assert.AreEqual(_viewModel.SelectedFigure.PointsCollection[0].X, new CustomPoint(0 + 5.5, 0 + 5.5).X);
            Assert.AreEqual(_viewModel.SelectedFigure.PointsCollection[1].X, new CustomPoint(1 + 5.5, 1 + 5.5).X);
            Assert.AreEqual(_viewModel.SelectedFigure.PointsCollection[2].X, new CustomPoint(5 + 5.5, 5 + 5.5).X);
            Assert.AreEqual(_viewModel.SelectedFigure.PointsCollection[3].X, new CustomPoint(7 + 5.5, 7 + 5.5).X);
        }

        [TestMethod]
        public void ChangeYCoordinateOfPoints()
        {
            //Arrange
            var xIncrement = 5.5;
            _viewModel.Canvas = new DrawingCanvas();
            _viewModel.SelectedFigure = new Line();
            _viewModel.SelectedFigure.PointsCollection.Add(new CustomPoint(0, 0));
            _viewModel.SelectedFigure.PointsCollection.Add(new CustomPoint(1, 1));
            _viewModel.SelectedFigure.PointsCollection.Add(new CustomPoint(5, 5));
            _viewModel.SelectedFigure.PointsCollection.Add(new CustomPoint(7, 7));
            //Act
           // _viewModel.IncrementYCoordinateOfPointsInFigure(xIncrement);
            //Assert
            Assert.AreEqual(_viewModel.SelectedFigure.PointsCollection[0].Y, new CustomPoint(0 + 5.5, 0 + 5.5).Y);
            Assert.AreEqual(_viewModel.SelectedFigure.PointsCollection[1].Y, new CustomPoint(1 + 5.5, 1 + 5.5).Y);
            Assert.AreEqual(_viewModel.SelectedFigure.PointsCollection[2].Y, new CustomPoint(5 + 5.5, 5 + 5.5).Y);
            Assert.AreEqual(_viewModel.SelectedFigure.PointsCollection[3].Y, new CustomPoint(7 + 5.5, 7 + 5.5).Y);
        }

        #endregion

        #region Scale SelectedFigure

        [TestMethod]
        public void ScaleXCoordinateInFigure()
        {
            //Arrange
            _viewModel.SelectedFigure = new Line();
            _viewModel.SelectedFigure.PointsCollection.Add(new CustomPoint(0, 0));
            _viewModel.SelectedFigure.PointsCollection.Add(new CustomPoint(1, 1));
            _viewModel.SelectedFigure.PointsCollection.Add(new CustomPoint(5, 5));
            _viewModel.SelectedFigure.PointsCollection.Add(new CustomPoint(7, 7));
            _viewModel.SelectedFigure.PointsCollection[0].IsVertex = true;
            _viewModel.SelectedFigure.PointsCollection[1].IsVertex = true;
            _viewModel.SelectedFigure.PointsCollection[2].IsVertex = true;
            _viewModel.SelectedFigure.PointsCollection[3].IsVertex = true;
            double incremet = 5.2;
            //Act
            //_viewModel.ScaleOnXCoordinate(incremet);
            //Assert
            Assert.AreEqual(_viewModel.SelectedFigure.PointsCollection[0].X, 0 * 5.2);
            Assert.AreEqual(_viewModel.SelectedFigure.PointsCollection[1].X, 1 * 5.2);
            Assert.AreEqual(_viewModel.SelectedFigure.PointsCollection[2].X, 5 * 5.2);
            Assert.AreEqual(_viewModel.SelectedFigure.PointsCollection[3].X, 7 * 5.2);
        }

        #endregion

        
    }

}